//  Carnival of Doom
//  Created by Shan Pratapagiri and Bassam Saeed.

import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;

public class Game extends JFrame implements KeyListener
{
	static final int WIDTH = 640;
	static final int HEIGHT = 480;
	static final int SIZE = 16;

	static int setLevel = 1;
	static int bombTime = 1;
	static int deathTime = 1;
	
	static boolean increment = true;
	static boolean levelChange = false;
	static boolean titlescreen = true;
	
	static Random rand = new Random ();
	static Graphics2D graphics;
	static PaintSurface canvas;
	static Font font;
	
	Map end, start, level;
	Bomb[] bombs;
	Mover[] flash;
	Ball ball;
	
	public static void main (String[] args)
	{
		new Game ();
	}

	public Game ()
	{
		this.setSize (WIDTH, HEIGHT);
		this.setTitle ("Carnival of Doom");
		this.setResizable (false);
		this.getContentPane ().setBackground (Color.BLACK);
		this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

		canvas = new PaintSurface ();

		canvas.setFocusable (true);
		canvas.addKeyListener (this);

		this.getContentPane ().add (canvas);
		this.setVisible (true);

		while (true)
		{
			canvas.repaint ();

			try
			{
				Thread.sleep (20);
			}
			catch (Exception e)
			{
			}
		}
	}

	public static boolean increment ()
	{
		return increment;
	}
	
	public static void setLevel ()
	{
		setLevel++;
		Ball.setLevel(setLevel);
		levelChange = true;
	}

	public void keyPressed (KeyEvent e)
	{
		int keyCode = e.getKeyCode ();

		if (keyCode == KeyEvent.VK_UP)
			ball.setYSpeed (-2);
		else if (keyCode == KeyEvent.VK_DOWN)
			ball.setYSpeed (2);
		else if (keyCode == KeyEvent.VK_RIGHT)
			ball.setXSpeed (2);
		else if (keyCode == KeyEvent.VK_LEFT)
			ball.setXSpeed (-2);
		else if (keyCode == KeyEvent.VK_SPACE)
            titlescreen = false;
	}

	public void keyReleased (KeyEvent e)
	{
		int keyCode = e.getKeyCode ();

		if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN)
			ball.setYSpeed (0);
		else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_LEFT)
			ball.setXSpeed (0);
	}

	public void keyTyped (KeyEvent e){}
	
	private class PaintSurface extends JComponent
	{
	
		{
			change();
		}
	
		public void change ()
		{
			if (setLevel == 1)
			{
				end = new Map (Game.WIDTH - (128 + SIZE), Game.HEIGHT / 2 - SIZE / 2, SIZE, SIZE);
				start = new Map (128, Game.HEIGHT / 2 - SIZE / 2, SIZE, SIZE);
				level = new Map ((int) (start.getX()), (int) (start.getY()), (int) (end.getX() + end.getWidth() - start.getX ()), SIZE);

				bombs =  new Bomb[11];

				ball = new Ball (10, start.getX(), start.getY(), start.getWidth(), start.getHeight());
				
				for (int i = 0; i < 11; i++)
					bombs[i] = new Bomb (start.getX() + start.getWidth() + 16 + (i * 32), level.getY() + level.getHeight() - level.getHeight() / 2 - 5);

				ball.reference(level, end, bombs);
			}
			else if (setLevel == 2)
			{
				start = new Map (Game.WIDTH - 144, Game.HEIGHT - 160, SIZE, SIZE);
				end = new Map (Game.WIDTH / 5, (int) (start.getY() - 208), SIZE, SIZE);
				level = new Map((int) (end.getX()), (int) (end.getY()), (int) (start.getX() + start.getWidth() - end.getX()), (int) (start.getY() + start.getHeight() - end.getY()));

				flash = new Mover[12];
				
				ball = new Ball (10, start.getX(), start.getY(), start.getWidth(), start.getHeight());

				for (int i = 0; i< 12; i++)
				{
					flash[i] = new Mover (rand.nextInt((int) (level.getWidth() - level.getX())) + (int) level.getX(), (int) (level.getY() + end.getHeight() + end.getHeight() / 2 - 5 + (i * 16)));
					flash[i].reference (level);
				}
				
				ball.reference(level, end, flash);
			}
			else if (setLevel == 3)
			{
				
			}
		}

		public void paint (Graphics g)
		{
			graphics = (Graphics2D) g;
			graphics.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			if (levelChange)
			{
				levelChange = false;
				change();
			}
			
			level.level ();
			start.start ();
			end.end ();

			if (!titlescreen)
				ball.move ();

			ball.detect ();

			if (titlescreen)
			{
				g.setColor (Color.white);
				g.drawString ("Press [SPACE] to Start", 335, 275);
			}

			if (ball.getDeath())
			{
				font = new Font("Verdana", Font.PLAIN, 10);
				g.setFont (font);
				g.drawString ("You just died! Start from the beginning.", 220, 400);

				deathTime++;

				if (deathTime == 50)
				{
					ball.setDeath (false);
					deathTime = 1;
				}
			}
			
			if (setLevel == 1)
			{
				if (bombTime == 0 || bombTime == 50)
				increment = !increment;

				if (increment)
				{
					for (int i = 0; i < 11; i++)
						g.drawImage (bombs[i].img, bombs[i].getXPos(), bombs[i].getYPos(), this);
					
					bombTime++;
				}
				else
				bombTime--;
			}
			
			if (setLevel == 2)
				for (int i = 0; i < 12; i++)
				{
					g.drawImage (flash[i].img, flash[i].getXPos(), flash[i].getYPos(), this);
					flash[i].move();
					flash[i].detect();
				}
		}
	}
}